package name.fowler.refactoring.simplestore;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author jlebedeva
 */
public class Report {

    private List<String> variables;
    private List<String> reportBuilder;

    public Report(List<String> template, String...variables) {
        this.variables = Arrays.asList(variables);
        this.reportBuilder = template;
    }
 
    public void replace(String key, Object value) {
        if (!variables.contains(key)) return;

        for (int i = 0; i < reportBuilder.size(); i++) {
            String line = reportBuilder.get(i);
            while (line.contains(key)) {
                line = line.replace(key, value.toString());
            }
            reportBuilder.set(i, line);
        }
    }
    
    public void replace(String key, List<? extends Object> values) {
        replace(key, values, true);
    }
    
    public void replace(String key, List<? extends Object> values, boolean addLines) {
        if (!variables.contains(key)) return;
        
        if (addLines) {
            addLines(key, values.size());
        }
        
        int currentIndex = 0;
        for (int i = 0; i < reportBuilder.size(); i++) {
            String line = reportBuilder.get(i);
            
            while (line.contains(key)) {
                line = line.replace(key, values.get(currentIndex++).toString());
            }
            reportBuilder.set(i, line);
        }
    }
    
    public String build() throws Exception {
        if (!isReady()) throw new IllegalStateException();
        
        StringBuilder sb = new StringBuilder();
        for (String line : reportBuilder) {
            sb.append(line);
        }
        return sb.toString();
    }
    
    private void addLines(String key, int times) {
        List<String> result = new ArrayList<String>();
        for (String s : reportBuilder) {
            if (s.contains(key)) {
                for (int i = 0; i < times; i++) {
                    result.add(s);
                }
            } else {
                result.add(s);
            }
        }
        reportBuilder = result;
    }

    private boolean isReady() {
        for (String line : reportBuilder) {
            for (String variable : variables) {
                if (line.contains(variable)) {
                    System.out.println(reportBuilder);
                    return false;
                }
            }
        }
        return true;
    }
}
